import os,sys,re

packageName = ''
className = ''
NameStack = []
count = 0
vmap = {}
omap = {}
fmap = {}
isWaiting = False
isPrinting = False
total = 0
fName = ''

def loopForFiles(r) :
    global packageName
    global isPrinting
    global fName

    for root,dirs,files in os.walk(r):
        for f in files:
            if re.search(r'\.java$', f.lower()):
                packageName = root[len(r):].replace('/', '.')
                fName = ' file: ' + f
                __analyseJavaFile(root + '/' + f)

def __analyseJavaFile(f) :
    global className
    global isWaiting

    isInComment = False
    className = ''
    isWaiting = False

    fileHandle = open(f)

    try:
        for line in fileHandle.readlines() :
            if line.find('/*') != -1 and line.find('*/') != -1:
                __analyseInstruction(line[0:line.index('/*')])
                __analyseInstruction(line[line.index('*/') + 2:])
            elif line.find('/*') != -1 :
                isInComment = True
                line = line[0:line.index('/*')]
                __analyseInstruction(line)
            elif line.find('*/') != -1 :
                isInComment = False
                line = line[line.index('*/') + 2:]
                __analyseInstruction(line)
            elif not isInComment:
                __analyseInstruction(line)
            
    finally:
        fileHandle.close()

def __analyseInstruction(s):
    global className
    global count
    global isWaiting
    global packageName
    global isPrinting
    global vmap
    global total
    global fName

    s = s.strip()
    if s:
        if isWaiting :
            vmap[vmap['Waiting Next Line']] = vmap[vmap['Waiting Next Line']] + s.split(';')[0].strip()
            isWaiting = False
        else:
            cn = __getClassOrInterfaceName(s)
            if cn != None :
                if className == '' :
                    className = packageName + '.' + cn
                else :
                    NameStack.append(className)
                    className = className + '$' + cn
                count = 1
            else :
                if s.find('{') != -1 :
                    count = count + 1
                if s.find('}') != -1 :
                    count = count - 1
                    if count == 0 :
                        if len(NameStack)  != 0 :
                            className = NameStack.pop()
                            count = 1

                if s.find('public static final Uri') != -1:
                    #print packageName + ' ' + s
                    total += 1

                if s.find('public static final') != -1 and s.find('=') != -1 :
                    if s.find('String ') != -1 or s.find('Uri ') != -1:
                        kv = s.split('=')
                        key = className + '.' + kv[0].strip().split()[-1]
                        if s.find('Uri ') != -1:
                            omap[key] = ''
                        if kv[1] == '' or kv[1].find(';') == -1:
                            isWaiting = True
                            vmap['Waiting Next Line'] = key
                            vmap[key] = kv[1].strip()
                        else :
                            vmap[key] = kv[1][0:kv[1].find(';')].strip()

def __getClassOrInterfaceName(s) :

    i1 = s.find('public')
    i2 = s.find('class')
    i3 = s.find('interface')
    j = s.find('{')
    if i1 != -1 and i2 != -1:
        i2 += len('class ')
        tn = s[i2:]
        return tn[:tn.find(' ')].strip()
    elif i1 != -1 and i3 != -1:
        i3 += len('interface ')
        tn = s[i3:]
        return tn[:tn.find(' ')].strip()
    else :
        return None

def __fixVMap(key) :
    global vmap
    global omap

    if vmap[key][0] == '"' and vmap[key][-1] == '"':
        fmap[key] = vmap[key][1:-1]
    elif vmap[key].find('Uri.parse') != -1:
        if __setValue(key, vmap[key][len('Uri.parse('):-1].split('+')) and omap.has_key(key):
            omap[key] = fmap[key]
    elif vmap[key].find('Uri.withAppendedPath') != -1:
        if __setValue(key, vmap[key][len('Uri.withAppendedPath('):-1].split(',')) and omap.has_key(key):
            omap[key] = fmap[key]
    else:
        '''if __setValue(key, [vmap[key]]):
            omap[key] = fmap[key]'''
        if isinstance(vmap[key], int) or isinstance(vmap[key], float):
            fmap[key] = vmap[key]
        else:
            if __setValue(key, [vmap[key]]) and omap.has_key(key):
                omap[key] = fmap[key]

def __makePackageNames(fk, v):
    
    i1 = v.rfind('.')
    if i1 != -1:
        cl = v[0:i1]
        va = v[i1 + 1:]
        i2 = fk.find(cl)
        if i2 != -1:
            name = fk[0:i2 + len(cl)] + '.' + va
            return [name]

    ret = []
    fk = fk[:fk.rfind('.')]
    while fk.rfind('$') != -1:
        if i1 != -1:
            ret.append(fk + '$' + v)
        else:
            ret.append(fk + '.' + v)
        fk = fk[:fk.rfind('$')]
    while fk.rfind('.') != -1:
        ret.append(fk + '.' + v)
        fk = fk[:fk.rfind('.')]
    
    ret.append(fk + '.' + v)
    ret.append('')
    return ret

def __setValue(fk, sps):
    global vmap
    global omap
    global fmap

    rf = True
    res = ''

    for u in sps:
        u = u.strip()
        if u[0] == '"' and u[-1] == '"':

            if res != '' and res[-1] != '/' and u[1] != '/':
                res = res + '/' + u[1:-1]
            else:
                res += u[1:-1]
        else:
            flag = False
            names = __makePackageNames(fk, u)
            for name in names:
                #if fk == 'android.provider.ContactsContract$RawContactsEntit$PhoneLookup$CommonDataKinds$Email.CONTENT_URI':
                    #print 'Key: ' + name
                if (not fmap.has_key(name)) and vmap.has_key(name):
                    __fixVMap(name)

                if fmap.has_key(name):
                    #if fk == 'android.provider.ContactsContract$RawContactsEntit$PhoneLookup$CommonDataKinds$Email.CONTENT_URI':
                        #print name + ' ' + fmap[name]
                    if res != '' and fmap[name] != '' and res[-1] != '/' and fmap[name][0] != '/':
                        res = res + '/' + fmap[name]
                    else:
                        res += fmap[name]
                    flag = True
                    break

            if not flag:
                res += u
                rf = False
                #print 'missing ' + fk + ' ' + u

    fmap[fk] = res

    return rf

def __outPutInitValue(f) :
    global omap
    global vmap

    for key in vmap :
        if key != 'Waiting Next Line':
            __fixVMap(key)

    fileHandle = open(f, 'a')

    for key in omap :
        if omap[key] != '':
            fileHandle.write(key + ' ' + omap[key] + '\n')
        #else:
        #    fileHandle.write(key + ' @@@\n')
            

    fileHandle.close()

if __name__=="__main__":
    if os.path.exists('AndroidInit.txt'):
        os.remove('AndroidInit.txt')
    loopForFiles("/home/raiden/Work/android_source/frameworks/base/core/java/")
    __outPutInitValue('AndroidInit.txt')
    #print 'total: ' + str(total)
